package com.ly.demo.taach.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import com.ly.demo.taach.jdbc.bean.Page;

/**
 *	数据库操作助手类, 简化数据库操作, 通过简单的输入SQL语句和参数, 执行并返回结果
 */
public abstract class IDBHelper implements AutoCloseable {

	/**
	 * 	连接串
	 */
	protected static String url;
	/**
	 * 	用户名
	 */
	protected static String user;
	/**
	 * 	密码
	 */
	protected static String password;
	/**
	 * 	数据库连接
	 */
	protected Connection conn;

	/**
	 * 	构造函数, 创建连接. 思考: 加载驱动如何确保只加载一次?
	 */
	public IDBHelper() {
		try {
			// 创建连接
			this.conn = DriverManager.getConnection(url, user, password);
			// 关闭自动提交, 保证事务性
			this.conn.setAutoCommit(false);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 	获取连接
	 * @return
	 */
	public abstract Connection getConnection() throws SQLException;

	/**
	 * 	关闭连接
	 */
	public abstract void close() throws SQLException;

	/**
	 * 	提交
	 */
	public abstract void commit() throws SQLException;

	/**
	 * 	回滚
	 */
	public abstract void rollback() throws SQLException;

	/**
	 * 	更新数据库
	 * @param sql
	 * @param params
	 * @return
	 */
	public abstract int update(String sql, Object... params) throws SQLException;

	/**
	 * 	[扩展] 新增一行记录, 返回自增值的主键值
	 * @param sql
	 * @param primaryKeyName
	 * @param params
	 * @return
	 */
	public abstract Object insertOne(String sql, String primaryKeyName, Object... params) throws SQLException;

	/**
	 * 	查询多行数据
	 * @param sql
	 * @param params
	 * @return
	 */
	public abstract List<Map<String, Object>> selectListMap(String sql, Object... params) throws SQLException;

	/**
	 * 	[扩展] 查询单行数据
	 * @param sql
	 * @param params
	 * @return
	 */
	public abstract Map<String, Object> selectOneMap(String sql, Object... params) throws SQLException;

	/**
	 * 	[扩展] 查询单个值
	 * @param sql
	 * @param params
	 * @return
	 */
	public abstract Object selectValue(String sql, Object... params) throws SQLException;

	/**
	 * 	[扩展] 查询分页数据
	 * @param sql
	 * @param page		页码
	 * @param size		分页行数
	 * @param params
	 * @return
	 */
	public abstract Page<Map<String, Object>> selectPage(String sql, int page, int size, Object... params)
			throws SQLException;
}
